<?php
/*
 * 邻客互动 lnksns 高颜值论坛博客、社区圈子、积分商城系统 https://www.lnksns.vip
 * 邻客互动，为各类自媒体提供全面运营解决方案，助力自媒体运营成长。
 * 承接DQ、DX、DEDE、等各种PHP、SNS程序的定制开发业务,BUG修复业务！
 * 联系QQ：987501448 WX：nzkd01 
 */
/**
 *      This is NOT a freeware, use is subject to license terms
 *      应用名称: 邻客互动 应用中心
 *      应用开发者: 叶子
 *      开发者QQ: 987501448
 *      未经应用程序开发者/所有者的书面许可，不得进行反向工程、反向汇编、反向编译等，不得擅自复制、修改、链接、转载、汇编、发表、出版、发展与之有关的衍生产品、作品等
 *      版权所有: 互娱时代襄阳文化产业有限公司
 *      
 *      应用中心 插件安装
 */
declare(strict_types=1);

namespace app\appcenter\lib;

use think\facade\Cache;

class AppInstallService
{
 
    public static function install($request) {
        // 这里省略了版本判断逻辑，根据自己需要去写
        $root_path = app()->getRuntimePath(); 
        // 更新包信息

        //domain:domain,id:id
        $domain = $request['domain'];
        $id = $request['id'];
        $file_url = 'https://ext.lnksns.vip/api/v1/installapp?id='.$id.'&domain='.$domain; //更新包的下载地址
        
        Cache::set('install_'.md5($domain.'5156U347((*@!!616'.$id), '1', 20);
        
        $filename = gen_random_str(15).'.zip'; //更新包文件名称
        // 检查和创建文件夹
        $dir = $root_path . 'install/';
        if (!file_exists($dir)) {
            mkdir($dir, 0777, true);
        }
 
        // 下载更新包到本地并赋值文件路径变量
        $path = file_exists($dir.$filename) ? $dir.$filename : self::download_file($file_url,$dir,$filename);
        
        // 如果下载没成功就返回报错
        if (!file_exists($dir.$filename)) {
            return ["msg" => '插件下载失败！', "code" => 100];
        }
 
        // PHP解压的扩展类
        if(!class_exists("\ZipArchive"))
        {
            unlink($path);
            return ['code' => 100, 'msg' => '请安装ZipArchive扩展！'];
        }
 
        // 实例化ZipArchive
        $zip = new \ZipArchive();
        //打开压缩包
        if ($zip->open($path) === true) {
            $app = trim($zip->getNameIndex(0), '/');
            // 复制根目录，ROOT_PATH在入口文件已经定义了
            $toPath = app()->getBasePath().'/plugin';
            try {
                // 解压文件到toPath路径下，用于覆盖差异文件
                $zip->extractTo($toPath);
                // 必须销毁变量，否则会报错
                unset($zip);
                // 删除更新包
                unlink($path);
            } catch (\Exception $e) {
                unlink($path);
                return ["msg" => "没有[" . $toPath . "]目录的写入权限", "code" => 100];
            }
 
            //文件差异覆盖完成，开始安装
            $class = "app\\plugin\\".$app."\\\config"::class;
            if (method_exists($class,'install')) {
                $class::install();
            }


            // if(file_exists(ROOT_PATH . "/sql.php")){
            //     // 这里的数据库是.php文件，是可执行的php代码，不是.sql数据库文件，记住！！！
            //     include $root_path . "/sql.php";
            //     chmod($root_path . "/sql.php",0777);
            //     unlink($root_path . "/sql.php");
            // }
            // 更新完成
            return ["msg" => "插件安装完成！", "code" => 200];
        } else {
            // 压缩包打开失败，删除文件并且返回报错
            unlink($path);
            return ["msg" => "插件包解压失败，请重试！", "code" => 100];
        }
    }


    /*
    * 文件下载方法
    * $url 文件下载地址
    * $dir 存储的文件夹
    * $filename 文件名字
    */
    public static function download_file($url, $dir, $filename = '') {
        if (empty($url)) {
            return false;
        }
        $ext = strrchr($url, '.');
 
        $dir = realpath($dir);
        //目录+文件
        $filename = (empty($filename) ? '/' . time() . '' . $ext : '/' . $filename);
        $filename = $dir . $filename;
        
        //开始捕捉
        ob_start();
 
        try {
            readfile($url);
        } catch (\Exception $e) {
            return ["msg" => "插件下载失败，请联系开发人员！", 'code' => 100];
        }

        $img = ob_get_contents();
        readfile($url);
        ob_end_clean();
        $size = strlen($img);
        $fp2 = fopen($filename, "a");
        fwrite($fp2, $img);
        fclose($fp2);
        return $filename;
    }



}
